﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;

namespace SvnLightClient
{
    class Utils
    {
        public static void ZipDirectory(string zipFileName, string sourceDirectory, string password="")
        {
            var zipper = new FastZip();
            zipper.Password = password;
            zipper.CreateZip(zipFileName, sourceDirectory, true, null);
        }

        public static void OpenFolder(string directory)
        {
            System.Diagnostics.Process.Start("Explorer", "/select,\"" + directory + "\"");
        }

        #region customed zip 
        public static void ZipFileDictory(string folderToZip, string zipFileName, string password)
        {
            if (!Directory.Exists(folderToZip))
            {
                throw new ArgumentException(string.Format("Directory is not exits. {0}", folderToZip));
            }

            using (var s = new ZipOutputStream(File.Create(zipFileName)))
            {
                s.SetLevel(6);
                s.Password = password;
                ZipFileDictory(folderToZip, s, "");
            }
        }

        private static void ZipFileDictory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
        {
            string[] folders, filenames;
            ZipEntry entry = null;
            FileStream fs = null;
            Crc32 crc = new Crc32();

            try
            {
                //创建当前文件夹
                entry = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/")); //加上 “/” 才会当成是文件夹创建
                zipStream.PutNextEntry(entry);
                zipStream.Flush();

                //先压缩文件，再递归压缩文件夹 
                filenames = Directory.GetFiles(folderToZip);
                foreach (string file in filenames)
                {
                    //打开压缩文件
                    fs = File.OpenRead(file);

                    byte[] buffer = new byte[fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    entry = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)));

                    entry.DateTime = DateTime.Now;
                    entry.Size = fs.Length;
                    fs.Close();

                    crc.Reset();
                    crc.Update(buffer);

                    entry.Crc = crc.Value;
                    zipStream.PutNextEntry(entry);
                    zipStream.Write(buffer, 0, buffer.Length);
                }
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                    fs = null;
                }
                if (entry != null)
                {
                    entry = null;
                }
                GC.Collect();
                GC.Collect(1);
            }

            folders = Directory.GetDirectories(folderToZip);
            foreach (string folder in folders)
            {
                ZipFileDictory(folder, zipStream, Path.Combine(parentFolderName, Path.GetFileName(folderToZip)));
            }
        }
        #endregion
    }
}
